package remote

import (
	"github.com/astaxie/beego/config"
	"golang.org/x/crypto/ssh"
	"io"
	"log"
	"net"
)

func Forward() {
	// 获取配置文件
	conf, err := config.NewConfig("ini", "conf/app.conf")
	if err != nil {
		log.Fatalf("配置文件错误: %v", err)
	}
	username := conf.String("uat-git::username")
	password := conf.String("uat-git::password")
	addr := conf.String("uat-git::addr")
	localAddr := conf.String("uat-git::localAddr")
	remoteAddr := conf.String("uat-git::remoteAddr")

	// 设置跳板机
	clientConfig := &ssh.ClientConfig{
		User: username,
		Auth: []ssh.AuthMethod{
			ssh.Password(password),
		},
		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
			return nil
		},
	}

	// 获取本地连接
	localConn, err := net.Dial("tcp", localAddr)
	if err != nil {
		log.Fatalf("获取本地连接失败: %v", err)
	}

	// 拨号给跳板机
	sshClientConn, err := ssh.Dial("tcp", addr, clientConfig)
	if err != nil {
		log.Fatalf("拨号给跳板机失败: %s", err)
	}

	// 设置远程监听端口
	remoteListener, err := sshClientConn.Listen("tcp", remoteAddr)
	if err != nil {
		log.Fatalf("设置远程端口失败: %v", err)
	}

	for {
		// 远程服务器，监听端口，等待请求
		remoteConn, err := remoteListener.Accept()
		if err != nil {
			log.Fatalf("远程服务器监听失败: %v", err)
		}

		// 互相拷贝连接，实现转发
		go func() {
			_, err = io.Copy(localConn, remoteConn)
			if err != nil {
				log.Fatalf("连接拷贝失败: %v", err)
			}
		}()
		go func() {
			_, err = io.Copy(remoteConn, localConn)
			if err != nil {
				log.Fatalf("连接拷贝失败: %v", err)
			}
		}()
	}
}
